package com.yys.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.yys.common.to.user.RegistUserTo;
import com.yys.gulimall.member.entity.MemberLevelEntity;
import com.yys.gulimall.member.exception.PhoneExistException;
import com.yys.gulimall.member.exception.UsernameExistException;
import com.yys.gulimall.member.service.MemberLevelService;
import com.yys.gulimall.member.vo.MemberLoginVo;
import com.yys.gulimall.member.vo.SocialUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yys.common.utils.PageUtils;
import com.yys.common.utils.Query;

import com.yys.gulimall.member.dao.MemberDao;
import com.yys.gulimall.member.entity.MemberEntity;
import com.yys.gulimall.member.service.MemberService;
import org.springframework.web.client.RestTemplate;


@Service("memberService")
@Slf4j
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    private MemberLevelService memberLevelService;

    private String url = "https://api.weibo.com/2/users/show.json";


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void regist(RegistUserTo registUserTo) {
        MemberEntity memberEntity = new MemberEntity();

        MemberLevelEntity memberLevelEntity = memberLevelService.getDefaultLevel();
        // 设置默认等级
        memberEntity.setLevelId(memberLevelEntity.getId());
        //TODO 保证手机号用户名唯一,不唯一抛异常
        checkPhoneUnique(registUserTo.getPhone());
        checkUsernameUnique(registUserTo.getUsername());

        // 设置手机号
        memberEntity.setMobile(registUserTo.getPhone());
        // 设置用户名
        memberEntity.setUsername(registUserTo.getUsername());

        //设置昵称
        memberEntity.setNickname(registUserTo.getUsername());

        // 设置密码 , 需要加密存储 MD5加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String password = encoder.encode(registUserTo.getPassword());
        memberEntity.setPassword(password);

        baseMapper.insert(memberEntity);
    }

    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile" , phone));
        if(count > 0) {
            throw new PhoneExistException();
        }
    }

    @Override
    public void checkUsernameUnique(String username) throws UsernameExistException {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username" , username));
        if(count > 0) {
            throw new UsernameExistException();
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo memberLoginVo) {
        String loginAccount = memberLoginVo.getLoginAccount();
        // 数据库查询 account可以是用户名也可是手机号
        QueryWrapper<MemberEntity> queryWrapper = new QueryWrapper<MemberEntity>().eq("username" , loginAccount)
                .or().eq("mobile" , loginAccount);
        MemberEntity memberEntity = this.baseMapper.selectOne(queryWrapper);
        if(ObjectUtils.isNotNull(memberEntity)) {
            String password = memberEntity.getPassword();
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            if (encoder.matches(memberLoginVo.getPassword(),password)) {
                return memberEntity;
            }
        }
        return null;
    }

    @Override
    public MemberEntity login(SocialUser socialUser) {
        // 注册登录合并
        String uid = socialUser.getUid();

        // 判断当前用户是否已经注册到系统了
        MemberEntity member = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid" , uid));
        if(ObjectUtils.isNotNull(member)) {
            // 有则更新
            MemberEntity memberEntity = new MemberEntity();
            memberEntity.setId(member.getId());
            memberEntity.setAccessToken(socialUser.getAccess_token());
            memberEntity.setExpiresIn(socialUser.getExpires_in());
            this.updateById(memberEntity);

        } else {
            // 没有则注册
            MemberEntity memberEntity = new MemberEntity();
            // 获得社交用户的账号信息
            try {
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
                HashMap<String, String> params = new HashMap<>();
                params.put("access_token",socialUser.getAccess_token());
                params.put("uid",socialUser.getUid());
                String sendUrl = addParam(url, params);
                ResponseEntity<String> responseEntity = restTemplate.getForEntity(sendUrl, String.class);
                if(responseEntity.getStatusCode().is2xxSuccessful()) {
                    //查询成功 返回对象太大了就封装为jsonObject从里面取
                    String info = responseEntity.getBody();
                    JSONObject jsonObject = JSON.parseObject(info);
                    String name = jsonObject.getString("name");
                    String gender = jsonObject.getString("gender");
                    memberEntity.setNickname(name);
                    memberEntity.setGender("m".equals(gender) ?1:0);

                }
            } catch (Exception e) {
                log.info("微博获取用户信息失败: {}" , e.getMessage());
                memberEntity.setNickname("游客" + socialUser.getUid());
            }
            memberEntity.setSocialUid(socialUser.getUid());
            memberEntity.setAccessToken(socialUser.getAccess_token());
            memberEntity.setExpiresIn(socialUser.getExpires_in());

            this.save(memberEntity);

            member = memberEntity;
        }
        return member;
    }

    private String addParam(String baseUrl, HashMap<String, String> params) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(baseUrl).append("?");
        params.forEach((k,v) -> stringBuilder.append(k).append("=").append(v).append("&"));
        return stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
    }

}